package com.snow.starter.interceptor;

import com.snow.annotation.RequireLogin;
import com.snow.annotation.RequirePermission;
import com.snow.exception.LoginUserNotFoundException;
import com.snow.model.ILoginUser;
import com.snow.service.IAuthComponent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * auth认证权限拦截器
 *
 * @author by 13119
 */
@Slf4j
public class AuthInterceptor implements HandlerInterceptor {

    final IAuthComponent authComponent;

    public AuthInterceptor(IAuthComponent authComponent) {
        this.authComponent = authComponent;
    }

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (!(handler instanceof HandlerMethod)) {
            //404页面，直接过
            return true;
        }
        HandlerMethod method = (HandlerMethod) handler;
        RequireLogin requireLogin = method.getMethodAnnotation(RequireLogin.class);
        if (requireLogin != null && !requireLogin.value()) {
            log.warn("接口已添加@RequifeLogin为False，跳过登录校验");
            return true;
        }
        // 1 登录认证校验
        ILoginUser currentUser;
        try {
            currentUser = authComponent.getCurrentUser();
        } catch (LoginUserNotFoundException e) {
            log.warn("{}地址登录验证未通过，无法获取登录用户信息", request.getRequestURI());
            authComponent.onAuthFail(response);
            return false;
        }
        // 2 权限认证校验
        RequirePermission permissions = method.getMethodAnnotation(RequirePermission.class);
        if (permissions == null) {
            log.debug("接口所需权限为空，跳过权限校验");
            return true;
        }
        if (authComponent.havePermission(permissions)) {
            return true;
        }
        log.error("用户：{}({})访问接口：{} 权限校验失败", currentUser.getName(), currentUser.getAccount(), request.getRequestURI());
        authComponent.onPermissionFail(response);
        return false;
    }

}
